
package org.upt.dcda.impl;

import java.util.List;
import java.util.logging.Logger;

import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;

import org.upt.dcda.NotificationManagerBeanLocal;
import org.upt.dcda.NotificationManagerBeanRemote;
import org.upt.dcda.db.BookEntity;
import org.upt.dcda.db.NotificationEntity;
import org.upt.dcda.db.UserEntity;
import org.upt.dcda.exceptions.BookNotFoundException;
import org.upt.dcda.exceptions.BookstoreException;
import org.upt.dcda.exceptions.UserNotFoundException;

/**
 * Session Bean implementation class NotificationManagerBeanImpl
 */
@Stateless
@LocalBean
public class NotificationManagerBeanImpl implements NotificationManagerBeanRemote, NotificationManagerBeanLocal
{

	@PersistenceContext
	private EntityManager	entityManager;

	private final Logger	logger	= Logger.getLogger(this.getClass().getSimpleName());

	@Override
	@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
	public void addNotification(int userId, int bookId) throws BookstoreException
	{
		try
		{
			final UserEntity user = entityManager.find(UserEntity.class, userId);
			if (user == null)
				throw new UserNotFoundException();

			final BookEntity book = entityManager.find(BookEntity.class, bookId);
			if (book == null)
				throw new BookNotFoundException();

			NotificationEntity ne = new NotificationEntity();

			ne.setUser(user);
			ne.setBook(book);

			entityManager.persist(ne);
		}
		catch (BookstoreException be)
		{
			throw be;
		}
		catch (Throwable t)
		{
			throw new BookstoreException("Caught exception: " + t.toString(), t);
		}
	}

	@Override
	@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
	// @Schedule(minute = "*/1", hour = "*")
	public void sendNotifications() throws BookstoreException
	{
		try
		{
			logger.info("-> sendNotifications()");
			TypedQuery<NotificationEntity> query = entityManager.createNamedQuery(
					NotificationEntity.NOTIFICATION_GET_QUERY, NotificationEntity.class);

			List<NotificationEntity> notifications = query.getResultList();

			for (NotificationEntity notification : notifications)
			{
				sendNotification(notification.getUser(), notification.getBook());
				entityManager.remove(notification);
			}
			logger.info("<- sendNotifications()");
		}
		catch (BookstoreException be)
		{
			throw be;
		}
		catch (Throwable t)
		{
			throw new BookstoreException("Caught exception: " + t.toString(), t);
		}
	}

	private void sendNotification(UserEntity user, BookEntity book) throws BookstoreException
	{
		logger.info("-> sendNotification(user = " + user.getUserEmail() + ", book = " + book.getBookTitle() + ")");
		logger.info("<- sendNotification(user = " + user.getUserEmail() + ", book = " + book.getBookTitle() + ")");
	}
}
